/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jskat.basic;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ImageIcon;

/**
 *
 * @author Kai
 */
public class Deck {

    private Card[] cards;

    public Deck() {
        cards = new Card[32];
        init();
    }

    private void init() {
        //initialize Deck with all cards
        ImageIcon tmpImg = new ImageIcon();
        
        
        cards[0] = new Card("7", "Karo", 0, tmpImg);
        cards[1] = new Card("8", "Karo", 0, tmpImg);
        cards[2] = new Card("9", "Karo", 0, tmpImg);
        cards[3] = new Card("10", "Karo", 10, tmpImg);
        cards[4] = new Card("Bube", "Karo", 2, tmpImg);
        cards[5] = new Card("Dame", "Karo", 3, tmpImg);
        cards[6] = new Card("Koenig", "Karo", 4, tmpImg);
        cards[7] = new Card("Ass", "Karo", 11, tmpImg);
        cards[8] = new Card("7", "Herz", 0, tmpImg);
        cards[9] = new Card("8", "Herz", 0, tmpImg);
        cards[10] = new Card("9", "Herz", 0, tmpImg);
        cards[11] = new Card("10", "Herz", 10, tmpImg);
        cards[12] = new Card("Bube", "Herz", 2, tmpImg);
        cards[13] = new Card("Dame", "Herz", 3, tmpImg);
        cards[14] = new Card("Koenig", "Herz", 4, tmpImg);
        cards[15] = new Card("Ass", "Herz", 11, tmpImg);
        cards[16] = new Card("7", "Pik", 0, tmpImg);
        cards[17] = new Card("8", "Pik", 0, tmpImg);
        cards[18] = new Card("9", "Pik", 0, tmpImg);
        cards[19] = new Card("10", "Pik", 10, tmpImg);
        cards[20] = new Card("Bube", "Pik", 2, tmpImg);
        cards[21] = new Card("Dame", "Pik", 3, tmpImg);
        cards[22] = new Card("Koenig", "Pik", 4, tmpImg);
        cards[23] = new Card("Ass", "Pik", 11, tmpImg);
        cards[24] = new Card("7", "Kreuz", 0, tmpImg);
        cards[25] = new Card("8", "Kreuz", 0, tmpImg);
        cards[26] = new Card("9", "Kreuz", 0, tmpImg);
        cards[27] = new Card("10", "Kreuz", 10, tmpImg);
        cards[28] = new Card("Bube", "Kreuz", 2, tmpImg);
        cards[29] = new Card("Dame", "Kreuz", 3, tmpImg);
        cards[30] = new Card("Koenig", "Kreuz", 4, tmpImg);
        cards[31] = new Card("Ass", "Kreuz", 11, tmpImg);
        
        
    }

    public void shuffle() {
        //add the cards in cards shuffle possibility, where a list of selected cards is just randomly stuffed into the other
        Random tmpRan = new Random();
        Random tmpRanShuffleCount = new Random();
        Random tmpShuffleModus = new Random();
        Random tmpCardAmounttoSort = new Random();
        CopyOnWriteArrayList<Card> tmpLeftList = new CopyOnWriteArrayList();
        CopyOnWriteArrayList<Card> tmpRightList = new CopyOnWriteArrayList();
        int tmpDivider = tmpRan.nextInt(32);
        
        if (tmpDivider == 0) {
            tmpDivider = 16;
        }
        //determine the amount of times the cards shall be shuffled
        int tmpCounter = tmpRanShuffleCount.nextInt(tmpDivider * 20);
        for (int i = 0; i < tmpCounter; i++) {
            tmpDivider = tmpRan.nextInt(32);
        
        if (tmpDivider == 0) {
            tmpDivider = 16;
        }
            //partitioning the cards in two list
            for (int j = 0; j < cards.length; j++) {
                if (j <= tmpDivider) {
                    tmpLeftList.add(cards[j]);
                } else {
                    tmpRightList.add(cards[j]);
                }
                
            }
            int tmpSortDivider;
            int tmpModus;
            //shuffle right list into left list
            while (tmpRightList.size() > 0) {
                tmpSortDivider = tmpCardAmounttoSort.nextInt(tmpRightList.size());
                //determine shuffle modus to decide in which place cards shall be placed
                tmpModus = tmpShuffleModus.nextInt(3);

                if(tmpRightList.size() <= 1)
                {
                    tmpLeftList.add(0, tmpRightList.get(0));
                    tmpRightList.remove(0);
                }else{
                //modus == 0: add cards in the front
                if (tmpModus == 0) {
                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpLeftList.add(0, tmpRightList.get(j));
                    }
                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpRightList.remove(0);
                    }
                } else if (tmpModus == 1)//modus == 1: add cards in the middle
                {
                    tmpDivider = tmpCardAmounttoSort.nextInt(tmpLeftList.size());

                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpLeftList.add(tmpDivider, tmpRightList.get(j));
                    }
                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpRightList.remove(0);
                    }
                } else//modus == other; add cards in the end
                {
                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpLeftList.add(tmpRightList.get(j));
                    }
                    for (int j = tmpSortDivider; j >= 0; j--) {
                        tmpRightList.remove(0);
                    }
                }
                }
            }
            //set shuffled array 
            cards = tmpLeftList.toArray(cards);
            tmpLeftList.removeAll(tmpLeftList);
        }


        
    }

    public void deal(Player aPHear, Player aPDeal, Player aPSay, Skat aSkat)
    {
        CopyOnWriteArrayList<Card> tmpList = new CopyOnWriteArrayList();
        tmpList.addAll(Arrays.asList(cards));
        
        for(int i = 0; i < 3; i++)
        {
            cards[i].setPlayerName(aPHear.getName());
            aPHear.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        for (int i = 3; i < 6; i++) {
            cards[i].setPlayerName(aPDeal.getName());
            aPDeal.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        for (int i = 6; i < 9; i++) {
            cards[i].setPlayerName(aPSay.getName());
            aPSay.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        
        for (int i = 9; i < 11; i++) {
            aSkat.setCard(i, tmpList.get(i));
        }
        
        for (int i = 11; i < 15; i++) {
            cards[i].setPlayerName(aPHear.getName());
            aPHear.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        
        for (int i = 15; i < 19; i++) {
            cards[i].setPlayerName(aPDeal.getName());
            aPDeal.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        
        for (int i = 19; i < 23; i++) {
            cards[i].setPlayerName(aPSay.getName());
            aPSay.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        for (int i = 23; i < 26; i++) {
            cards[i].setPlayerName(aPHear.getName());
            aPHear.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        for (int i = 26; i < 29; i++) {
            cards[i].setPlayerName(aPDeal.getName());
            aPDeal.setSingleCardPlayerHand(i, tmpList.get(i));
        }
        for (int i = 29; i < 32; i++) {
            cards[i].setPlayerName(aPSay.getName());
            aPSay.setSingleCardPlayerHand(i, tmpList.get(i));
        }
    }

    public Card[] getCards() {
        return cards;
    }

    public void setCards(Card[] aCards) {
        cards = aCards;
    }
    
    public Card getCard(int anIndex)
    {
        if(anIndex < cards.length && anIndex >= 0 )
        {
            return cards[anIndex];
        }else
        {
            return null;
        }
        
    }
    
    public void setCard(int anIndex, Card aCard)
    {
        if(anIndex < cards.length && anIndex >= 0 )
        {
           cards[anIndex] = aCard;
        }
        
    }
}
